import UniUtil from './UniUtil';
import LoggerUtil from './LoggerUtil';

/**
 * 批量下载工具类
 */
export default class BatchDownloadUtil {

    /**
     * 并行批量下载文件
     * @param urls 要下载的文件URL数组
     * @param maxConcurrent 最大并发数，默认为3
     * @returns Promise<DownloadResult[]>
     */
    static async batchDownload(urls: string[], maxConcurrent: number = 3): Promise<DownloadResult[]> {
        if (!urls || urls.length === 0) {
            return [];
        }

        UniUtil.showLoading();

        try {
            // 使用Promise.all进行并行下载
            const results = await Promise.all(
                urls.map(url => this.downloadSingleFile(url))
            );

            UniUtil.hideLoading();

            const successCount = results.filter(r => r.success).length;
            const failCount = results.length - successCount;

            // 只在有失败的情况下显示详细信息，避免与系统提示重复
            if (failCount > 0) {
                UniUtil.showToast({ title: `下载完成，成功${successCount}个，失败${failCount}个` });
            }

            return results;

        } catch (error) {
            UniUtil.hideLoading();
            LoggerUtil.error("批量下载失败", error);
            UniUtil.showError({ title: "批量下载失败" });
            return [];
        }
    }

    /**
     * 限制并发数的批量下载
     * @param urls 要下载的文件URL数组
     * @param maxConcurrent 最大并发数
     * @returns Promise<DownloadResult[]>
     */
    static async batchDownloadWithLimit(urls: string[], maxConcurrent: number = 3): Promise<DownloadResult[]> {
        if (!urls || urls.length === 0) {
            return [];
        }

        UniUtil.showLoading();
        const results: DownloadResult[] = [];

        // 分批处理，控制并发数
        for (let i = 0; i < urls.length; i += maxConcurrent) {
            const batch = urls.slice(i, i + maxConcurrent);
            const batchResults = await Promise.all(
                batch.map(url => this.downloadSingleFile(url))
            );
            results.push(...batchResults);
        }

        UniUtil.hideLoading();

        const successCount = results.filter(r => r.success).length;
        const failCount = results.length - successCount;

        if (failCount === 0) {
            UniUtil.showToast({ title: `下载完成` });
        } else {
            UniUtil.showToast({ title: `下载完成，成功${successCount}个，失败${failCount}个` });
        }

        return results;
    }

    /**
     * 下载单个文件
     * @param url 文件URL
     * @returns Promise<DownloadResult>
     */
    private static downloadSingleFile(url: string): Promise<DownloadResult> {
        return new Promise((resolve) => {
            uni.downloadFile({
                url: url,
                success: (res) => {
                    // 下载成功后保存到相册
                    uni.saveImageToPhotosAlbum({
                        filePath: res.tempFilePath,
                        success: () => {
                            resolve({
                                url: url,
                                success: true,
                                filePath: res.tempFilePath,
                                error: null
                            });
                        },
                        fail: (err) => {
                            LoggerUtil.error(`保存文件失败: ${url}`, err);
                            resolve({
                                url: url,
                                success: false,
                                filePath: res.tempFilePath,
                                error: err.errMsg || '保存失败'
                            });
                        }
                    });
                },
                fail: (err) => {
                    LoggerUtil.error(`下载文件失败: ${url}`, err);
                    resolve({
                        url: url,
                        success: false,
                        filePath: null,
                        error: err.errMsg || '下载失败'
                    });
                }
            });
        });
    }

    /**
     * 仅下载文件到临时目录（不保存到相册）
     * @param urls 要下载的文件URL数组
     * @returns Promise<DownloadResult[]>
     */
    static async batchDownloadToTemp(urls: string[]): Promise<DownloadResult[]> {
        if (!urls || urls.length === 0) {
            return [];
        }

        UniUtil.showLoading();

        try {
            const results = await Promise.all(
                urls.map(url => this.downloadToTemp(url))
            );

            UniUtil.hideLoading();

            const successCount = results.filter(r => r.success).length;
            // UniUtil.showToast({ title: `下载完成，共${successCount}个文件` });

            return results;

        } catch (error) {
            UniUtil.hideLoading();
            LoggerUtil.error("批量下载失败", error);
            // UniUtil.showError({ title: "批量下载失败" });
            return [];
        }
    }

    /**
     * 下载文件到临时目录
     * @param url 文件URL
     * @returns Promise<DownloadResult>
     */
    private static downloadToTemp(url: string): Promise<DownloadResult> {
        return new Promise((resolve) => {
            uni.downloadFile({
                url: url,
                success: (res) => {
                    resolve({
                        url: url,
                        success: true,
                        filePath: res.tempFilePath,
                        error: null
                    });
                },
                fail: (err) => {
                    LoggerUtil.error(`下载文件失败: ${url}`, err);
                    resolve({
                        url: url,
                        success: false,
                        filePath: null,
                        error: err.errMsg || '下载失败'
                    });
                }
            });
        });
    }

    /**
     * 批量预览图片（替代下载到临时目录）
     * @param urls 要预览的图片URL数组
     * @param currentIndex 当前显示的图片索引，默认为0
     * @returns Promise<void>
     */
    static async previewImages(urls: string[], currentIndex: number = 0): Promise<void> {
        if (!urls || urls.length === 0) {
            UniUtil.showError({ title: "没有可预览的图片" });
            return;
        }

        try {
            uni.previewImage({
                urls: urls,
                current: currentIndex,
                longPressActions: {
                    itemList: ['保存图片', '发送给朋友'],
                    success: (tapRes) => {
                        if (tapRes.tapIndex === 0) {
                            // 用户选择保存图片
                            this.saveCurrentImage(urls[currentIndex]);
                        }
                    }
                }
            });
        } catch (error) {
            // LoggerUtil.error("预览图片失败", error);
            // UniUtil.showError({ title: "预览图片失败" });
        }
    }

    /**
     * 保存单张图片
     * @param url 图片URL
     * @returns Promise<boolean>
     */
    private static async saveCurrentImage(url: string): Promise<boolean> {
        return new Promise((resolve) => {
            uni.downloadFile({
                url: url,
                success: (res) => {
                    uni.saveImageToPhotosAlbum({
                        filePath: res.tempFilePath,
                        success: () => {
                            resolve(true);
                        },
                        fail: (err) => {
                            // LoggerUtil.error(`保存图片失败: ${url}`, err);
                            // UniUtil.showError({ title: "保存图片失败" });
                            resolve(false);
                        }
                    });
                },
                fail: (err) => {
                    // LoggerUtil.error(`下载图片失败: ${url}`, err);
                    // UniUtil.showError({ title: "下载图片失败" });
                    resolve(false);
                }
            });
        });
    }

    /**
     * 逐个保存图片（减少系统提示频率）
     * @param urls 要下载的文件URL数组
     * @param interval 每张图片保存间隔（毫秒），默认500ms
     * @returns Promise<DownloadResult[]>
     */
    static async batchDownloadWithDelay(urls: string[], interval: number = 500): Promise<DownloadResult[]> {
        if (!urls || urls.length === 0) {
            return [];
        }

        UniUtil.showLoading();
        const results: DownloadResult[] = [];

        try {
            for (let i = 0; i < urls.length; i++) {
                const result = await this.downloadSingleFile(urls[i]);
                results.push(result);

                // 如果不是最后一张图片，等待一段时间再保存下一张
                if (i < urls.length - 1) {
                    await new Promise(resolve => setTimeout(resolve, interval));
                }
            }

            UniUtil.hideLoading();

            const successCount = results.filter(r => r.success).length;
            const failCount = results.length - successCount;

            // if (failCount > 0) {
            //     UniUtil.showToast({ title: `保存完成` });
            // }

            return results;

        } catch (error) {
            UniUtil.hideLoading();
            LoggerUtil.error("批量下载失败", error);
            UniUtil.showError({ title: "批量下载失败" });
            return [];
        }
    }

    /**
     * 可选择保存方式的批量下载
     * @param urls 要下载的文件URL数组
     * @param saveToAlbum 是否保存到相册，false时只下载到临时目录
     * @param maxConcurrent 最大并发数，默认为3
     * @returns Promise<DownloadResult[]>
     */
    static async batchDownloadWithOption(urls: string[], saveToAlbum: boolean = false, maxConcurrent: number = 3): Promise<DownloadResult[]> {
        if (!urls || urls.length === 0) {
            return [];
        }

        UniUtil.showLoading();

        try {
            // 根据选项选择下载方式
            const downloadMethod = saveToAlbum ? this.downloadSingleFile : this.downloadToTemp;

            const results = await Promise.all(
                urls.map(url => downloadMethod.call(this, url))
            );

            UniUtil.hideLoading();

            const successCount = results.filter(r => r.success).length;
            const failCount = results.length - successCount;

            // const message =  `保存完成`;
            // UniUtil.showToast({ title: message });

            return results;

        } catch (error) {
            UniUtil.hideLoading();
            LoggerUtil.error("批量下载失败", error);
            UniUtil.showError({ title: "批量下载失败" });
            return [];
        }
    }
}

/**
 * 下载结果接口
 */
export interface DownloadResult {
    url: string;
    success: boolean;
    filePath: string | null;
    error: string | null;
}
